package com.library.librarybackend.service.impl;

import com.library.librarybackend.config.MinioConfig;
import com.library.librarybackend.domain.OSSObject;
import com.library.librarybackend.domain.enums.OSSEnum;
import com.library.librarybackend.service.OSSService;
import io.minio.*;
import io.minio.http.Method;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

/**
 * @author 平
 * @description MinIO服务实现类
 * @since 2025-09-21 13:51
 */
@Service
@RequiredArgsConstructor
public class MinIOServiceImpl implements OSSService {

    private final MinioClient minioClient;

    private final MinioConfig minioConfig;


    @Override
    @SneakyThrows
    public OSSObject upload(InputStream in, String type, String fileName, String path, Boolean isPrivate) {
        // 构建对象名称
        String objName = OSSEnum.isPrivate(isPrivate) + SEPARATOR + path + SEPARATOR + System.currentTimeMillis() + DASHED + fileName;
        // 获取大小
        int size = in.available();
        // 上传
        try (InputStream i = in) {
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(minioConfig.getBucketName())
                            .object(objName)
                            .stream(i, size, -1)
                            .build()
            );
        }
        // 返回存储对象
        return OSSObject.builder()
                .filename(fileName)
                .objName(objName)
                .type(type)
                .path(path)
                .size(size)
                .url(minioConfig.getDomain() + SEPARATOR + minioConfig.getBucketName() + SEPARATOR + objName)
                .build();
    }

    @Override
    @SneakyThrows
    public void delete(String objName) {
        minioClient.removeObject(
                RemoveObjectArgs.builder()
                        .bucket(minioConfig.getBucketName())
                        .object(objName)
                        .build()
        );
    }

    @Override
    @SneakyThrows
    public String preview(String objName, Integer expires, TimeUnit timeUnit) {
        return minioClient.getPresignedObjectUrl(
                GetPresignedObjectUrlArgs.builder()
                        .method(Method.GET)
                        .bucket(minioConfig.getBucketName())
                        .object(objName)
                        .expiry(expires, timeUnit)
                        .build()
        );
    }

    @Override
    @SneakyThrows
    public void download(String objName, Consumer<InputStream> consumer) {
        try (InputStream in = minioClient.getObject(
                GetObjectArgs.builder()
                        .bucket(minioConfig.getBucketName())
                        .object(objName)
                        .build())) {
            consumer.accept(in);
        }
    }

    @Override
    @SneakyThrows
    public InputStream download(String objName) {
        return minioClient.getObject(
                GetObjectArgs.builder()
                        .bucket(minioConfig.getBucketName())
                        .object(objName)
                        .build());
    }
}
